package com.xiaotu.spider.letv.pageprocessor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.TVRecordModel;
import com.xiaotu.common.model.TVSetsPlotModel;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.KeywordEncode;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.TVProcessUtils;
import com.xiaotu.spider.APageProcessor;

import net.sf.json.JSONObject;

/**
 * 爬取乐视电视剧记录信息[tab_tv_record]
 * @start spiderBrowserRun
 * @author subin
 */
@Component("LeTVPageProcessor")
@Scope("prototype")
public class LeTVPageProcessor extends APageProcessor
{
	
	@Override
	protected Request getStartRequest(JSONObject target)
	{
		return new Request("http://so.letv.com/s?wd="
				+ KeywordEncode.encode(target.getString("tvName")));
	}
	
	@Override
	protected String getSpiderType()
	{
		return Constants.SpiderTaskType.TV_LeTV;
	}
	
	@Override
	public String getPageDataType(Page page)
	{
		if (page.getUrl().toString().contains("http://so.letv.com/s?wd="))
			return Constants.PageDataType.SEARCH_LIST;
		else if (page.getUrl().toString()
				.contains("http://v.stat.letv.com/vplay/queryMmsTotalPCount"))
			return Constants.PageDataType.TV_RECORD;
		return Constants.PageDataType.TV_PLOTSET;
	}
	
	@Override
	public void process(Page page)
	{
		String dataType = this.getPageDataType(page);
		Map<String, Object> tvInfoMap = page.getRequest().getExtras();
		
		switch (dataType)
		{
			case Constants.PageDataType.SEARCH_LIST:
				this.searchListProcess(page, tvInfoMap);
				break;
			case Constants.PageDataType.TV_RECORD:
				this.tvRecordProcess(page, tvInfoMap);
				break;
			default:
				this.tvSetsProcess(page, tvInfoMap);
				break;
		}
	}
	
	private void searchListProcess(Page page, Map<String, Object> tvInfoMap)
	{
		
		List<String> linkList = new ArrayList<>();
		List<String> tvNameList = new ArrayList<>();
		List<String> tvTypes = new ArrayList<String>();
		List<List<String>> directorList = new ArrayList<List<String>>();
		List<List<String>> actorsList = new ArrayList<List<String>>();
		
		List<String> infoList = page.getHtml()
				.xpath("//div[@class='Sports-so' or @class='Movie-so' or @class='Tv-so']")
				.all();
		final List<Html> divObjList = new ArrayList<Html>();
		for (int i = 0; i < infoList.size(); i++)
		{
			Html html = new Html(infoList.get(i));
			String dataInfo = html.xpath("//div[@class='So-detail']/@data-info")
					.toString();
			
			if (StringUtils.isEmpty(dataInfo))
				continue;
			
			JSONObject dataObj = JSONObject.fromObject(dataInfo);
			if (!dataObj.has("pid") || !dataObj.has("keyWord"))
				continue;
			
			String link = html
					.xpath("//div[@class='so-cont']/div[@class='left']//a/@href")
					.get();
			if (StringUtils.isEmpty(link)
					|| !link.contains("http://www.letv.com"))
				continue;
			
			String keyWord = JSONObject.fromObject(dataInfo)
					.getString("keyWord");
			String[] splits = keyWord.split(" ");
			
			if (!this.tvMatched(html, splits[2]))// 花絮或预告片
				continue;
			
			List<String> titleList = html
					.xpath("//div[@class='info_list']/p[1]//a/@title").all();
			if(titleList.size() == 0){
				titleList = html
						.xpath("//div[@class='info_list']/p[2]//a/@title").all();
			}
			
			String directorsStr = titleList.get(0).substring(3);
			String actorsStr = titleList.get(titleList.size() - 1).substring(3);
			
			directorList.add(Arrays.asList(directorsStr.split(",")));
			actorsList.add(Arrays.asList(actorsStr.split(",")));
			
			tvTypes.add(splits[2]);
			tvNameList.add(splits[0]);
			
			linkList.add(
					"http://v.stat.letv.com/vplay/queryMmsTotalPCount?callback=jQuery17106255796970220189_1463020612741&pid="
							+ dataObj.getString("pid"));
			divObjList.add(html);
			
			String firstTime =html.xpath("//div[@class='info_list']/p[2]/span[1]/a/text()").toString();
			tvInfoMap.put("firstTime", firstTime);
		}
		
		TVProcessUtils.addTVFromSearchList(page, tvInfoMap, tvNameList,
				linkList, tvTypes, actorsList, directorList, null,
				new TVProcessUtils.UpdateSetGetter()
				{
					@Override
					public String getUpdateSet(int idx)
					{
						return divObjList.get(idx)
								.xpath("//div[@class='so-cont']//span[@class='bottom_txt']/text()")
								.regex("更新至" + RegexUtils.REGEX_INTEGER + "集")
								.regex(RegexUtils.REGEX_INTEGER).get();
					}
				});
	}
	
	/**
	 * 如果是电视剧，则过滤掉花絮
	 * @param divObj
	 * @param tvType
	 * @return 是否为电视剧，而非花絮
	 */
	private boolean tvMatched(Html divObj, String tvType)
	{
		String divHtml = divObj.toString();
		if (RegexUtils.regexFind("\\[预告.*\\]|\\[花絮\\]", divHtml))
			return false;
		return true;
	}
	
	private void tvRecordProcess(Page page, Map<String, Object> tvInfoMap)
	{
		String search = page.getRawText();
		if (StringUtils.isEmpty(search))
			throw new SpiderException(
					SpiderExceptionCode.DataInvalideException);
		
		search = search.substring(search.indexOf("{"),
				search.lastIndexOf("}") + 1);
		
		JSONObject tvObject = JSONObject.fromObject(search);
		
		String score = tvObject.getString("plist_score").trim();
		String playCount = tvObject.getString("plist_play_count");
		if (playCount.equals("0") && score.equals("0"))
			throw new SpiderException(
					SpiderExceptionCode.DataInvalideException);
		if (!RegexUtils.regexMatch(RegexUtils.REGEX_NUMBER, score))
			score = null;
		page.putField(TVRecordModel.class.getName(),
				new TVRecordModel(tvInfoMap.get("tvid") + "",
						TVProcessUtils.getPageTVName(tvInfoMap),
						Constants.SiteName.LETV, score, playCount, null, null,
						null, null,
						TVProcessUtils.getPageUpdateSet(tvInfoMap),tvInfoMap.get("firstTime") + ""));
		
	}
	
	private void tvSetsProcess(Page page, Map<String, Object> tvInfoMap)
	{
		
		List<String> setList = page.getHtml()
				.xpath("//div[@class='listText']/div[@class='list active']/dl[@class='w120']/dd/p[@class='p2']/text()")
				.all();
		if (setList == null || setList.isEmpty())
			throw new SpiderException(
					SpiderExceptionCode.DataInvalideException);
		
		List<TVSetsPlotModel> setsList = new ArrayList<TVSetsPlotModel>();
		for (int i = 0; i < setList.size(); i++)
			setsList.add(new TVSetsPlotModel(tvInfoMap.get("tvid") + "",
					tvInfoMap.get("tvName") + "", (i + 1) + "",
					setList.get(i)));
		if (!setsList.isEmpty())
			page.putField(TVSetsPlotModel.class.getName() + "List", setsList);
		
	}
}
